package com.ruowei.modules.wxpay.web.task;

import com.querydsl.jpa.impl.JPAQueryFactory;
import com.ruowei.modules.foodOrder.domain.QOrder;
import com.ruowei.modules.foodOrder.domain.RefundApplication;
import com.ruowei.modules.foodOrder.domain.enumeration.FlowType;
import com.ruowei.modules.foodOrder.domain.enumeration.OrderStatus;
import com.ruowei.modules.foodOrder.repository.OrderRepository;
import com.ruowei.modules.foodOrder.repository.RefundApplicationRepository;
import com.ruowei.modules.foodOrder.service.LifeCycleService;
import com.ruowei.modules.foodOrder.service.MerchantService;
import com.ruowei.modules.foodOrder.service.PaymentFlowService;
import com.ruowei.modules.wxpay.service.WeChatPayService;
import lombok.extern.slf4j.Slf4j;
import org.springframework.scheduling.annotation.Scheduled;
import org.springframework.stereotype.Component;

import java.time.Instant;
import java.util.Map;
import java.util.Optional;

@Component
@Slf4j
//处理退款订单定时任务
public class HandleRefundOrderTask {
    private final QOrder qOrder = QOrder.order;
    private final WeChatPayService weChatPayService;
    private final JPAQueryFactory jpaQueryFactory;
    private final OrderRepository orderRepository;
    private final RefundApplicationRepository refundApplicationRepository;
    private final LifeCycleService lifeCycleService;
    private final PaymentFlowService paymentFlowService;
    private final MerchantService merchantService;

    public HandleRefundOrderTask(WeChatPayService weChatPayService, JPAQueryFactory jpaQueryFactory, OrderRepository orderRepository, RefundApplicationRepository refundApplicationRepository, LifeCycleService lifeCycleService, PaymentFlowService paymentFlowService, MerchantService merchantService) {
        this.weChatPayService = weChatPayService;
        this.jpaQueryFactory = jpaQueryFactory;
        this.orderRepository = orderRepository;
        this.refundApplicationRepository = refundApplicationRepository;
        this.lifeCycleService = lifeCycleService;
        this.paymentFlowService = paymentFlowService;
        this.merchantService = merchantService;
    }

    /**
     * @param
     * @apiNote 每3秒执行一次  跟微信退款回调接口功能一样
     * 处理退款的订单 查询微信中的订单状态 更新系统的订单状态
     * @author 董兴
     * @date 2020年11月13日
     */
    //@Scheduled(cron = "*/5 * * * * ?")
    public void handleRefundOrder() {
        jpaQueryFactory.selectFrom(qOrder)
            .where(qOrder.status.in(OrderStatus.CANCELLING, OrderStatus.REFUND_AGREE, OrderStatus.MERCHANT_REFUSE_TO_RECEIVE))
            .fetch()
            .forEach(order -> {
                try {
                    String message = "";
                    Map<String, String> map = weChatPayService.refundQuery(order.getOrderCode());
                    if (map.get("return_code").equals("SUCCESS") && map.get("result_code").equals("SUCCESS")) {
                        String orderReturnCode = map.get("out_refund_no_0") == null ? "" : map.get("out_refund_no_0");
                        if (map.get("refund_status_0") != null) {
                            switch (map.get("refund_status_0")) {
                                case "SUCCESS": {
                                    Optional<RefundApplication> applicationOptional = refundApplicationRepository.findFirstByOrderCodeOrderByTimeDesc(order.getOrderCode());
                                    if (applicationOptional.isPresent()) {
                                        RefundApplication application = applicationOptional.get();
                                        if (order.getStatus().equals(OrderStatus.CANCELLING)) {
                                            application.setStatus(OrderStatus.CANCELLED);
                                        } else {
                                            application.setStatus(OrderStatus.REFUNDED);
                                        }
                                        refundApplicationRepository.saveAndFlush(application);
                                    }

                                    if (order.getStatus().equals(OrderStatus.CANCELLING)) {
                                        order.setStatus(OrderStatus.CANCELLED);
                                    } else {
                                        order.setStatus(OrderStatus.REFUNDED);
                                    }
                                    //保存流水
                                    paymentFlowService.savePaymentFlow(order.getOrderCode(),
                                        orderReturnCode,
                                        order.getMemberCode(),
                                        FlowType.REFUND,
                                        order.getMerchantCode(),
                                        merchantService.getMerchantNameBy(order.getMerchantCode()),
                                        order.getPayAmount());

                                    lifeCycleService.saveLifeCycle(order.getOrderCode(), orderReturnCode, "退款成功", "您的退款已返回到原账户，请注意查收", false);
                                    order.setUpdateTime(Instant.now());
                                    orderRepository.saveAndFlush(order);

                                    message = "【微信退款状态】退款成功";
                                    break;
                                }
                                case "REFUNDCLOSE": {
                                    order.setStatus(OrderStatus.REFUND_CLOSED);
                                    order.setUpdateTime(Instant.now());
                                    orderRepository.saveAndFlush(order);

                                    Optional<RefundApplication> applicationOptional = refundApplicationRepository.findFirstByOrderCodeOrderByTimeDesc(order.getOrderCode());
                                    if (applicationOptional.isPresent()) {
                                        RefundApplication application = applicationOptional.get();
                                        application.setStatus(OrderStatus.REFUND_CLOSED);
                                        refundApplicationRepository.saveAndFlush(application);
                                    }
                                    lifeCycleService.saveLifeCycle(order.getOrderCode(), orderReturnCode, "退款关闭", "您的退款已关闭", false);

                                    message = "【微信退款状态】退款关闭";
                                    break;
                                }
                                case "PROCESSING": {
                                    message = "【微信退款状态】退款处理中";
                                    break;
                                }
                                case "CHANGE": {
                                    order.setStatus(OrderStatus.REFUND_FAILED);
                                    order.setUpdateTime(Instant.now());
                                    orderRepository.saveAndFlush(order);

                                    Optional<RefundApplication> applicationOptional = refundApplicationRepository.findFirstByOrderCodeOrderByTimeDesc(order.getOrderCode());
                                    if (applicationOptional.isPresent()) {
                                        RefundApplication application = applicationOptional.get();
                                        application.setStatus(OrderStatus.REFUND_FAILED);
                                        application.setDescription("退款异常，退款到银行发现用户的卡作废或者冻结了，导致原路退款银行卡失败，可前往商户平台（pay.weixin.qq.com）-交易中心，手动处理此笔退款。");
                                        refundApplicationRepository.saveAndFlush(application);
                                    }
                                    lifeCycleService.saveLifeCycle(order.getOrderCode(), orderReturnCode, "退款异常", "退款异常，退款到银行发现用户的卡作废或者冻结了，导致原路退款银行卡失败，可前往商户平台（pay.weixin.qq.com）-交易中心，手动处理此笔退款。", false);

                                    message = "【微信退款状态】退款异常，退款到银行发现用户的卡作废或者冻结了，导致原路退款银行卡失败，可前往商户平台（pay.weixin.qq.com）-交易中心，手动处理此笔退款。";
                                    break;
                                }
                            }
                        }
                    }
                    log.info(message);
                } catch (Exception e) {
                    e.printStackTrace();
                }
            });
    }
}
